package com.zhengshang.api.controller;

import com.alibaba.fastjson.JSONObject;
import com.zhengshang.api.domain.AppAdvertisementRecord;
import com.zhengshang.api.domain.AppSigninRecord;
import com.zhengshang.api.service.IAppAdvertisementRecordService;
import com.zhengshang.api.service.IAppSigninRecordService;
import com.zhengshang.common.annotation.RepeatSubmit;
import com.zhengshang.common.constant.app.AppConstant;
import com.zhengshang.common.core.controller.BaseController;
import com.zhengshang.common.core.domain.AjaxResult;
import com.zhengshang.common.core.domain.entity.SysUser;
import com.zhengshang.common.core.domain.model.LoginAppUser;
import com.zhengshang.common.utils.DateUtils;
import com.zhengshang.common.utils.StringUtils;
import com.zhengshang.common.utils.sign.Md5Utils;
import com.zhengshang.common.utils.sign.Sha256Util;
import com.zhengshang.common.utils.uuid.IdUtils;
import com.zhengshang.security.service.TokenService;
import com.zhengshang.system.service.ISysConfigService;
import com.zhengshang.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.Date;
import java.util.List;

/**
 * @author HY
 * @version 1.0.0
 * @ClassName LoginController.java
 * @Description TODO
 * @createTime 2020年12月03日 10:09
 */
@Api(tags = "广告模块")
@RequestMapping("/advertisement")
@RestController
public class AdvertisementController extends BaseController {

    @Autowired
    private TokenService tokenService;
    @Autowired
    private IAppSigninRecordService signinRecordService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private IAppAdvertisementRecordService appAdvertisementRecordService;
    //最少签到次数
    private static final Integer maxCount = 10;

    /**
     * @throws
     * @title 用户签到
     * @description
     * @author admin
     * @updateTime 2021/3/4 9:12
     */
    @PreAuthorize("@ss.hasPermi('app:advertisement:signIn')")
    @ApiOperation(value = "用户签到")
    @RepeatSubmit
    @PostMapping("/signIn")
    public AjaxResult signIn(
            HttpServletRequest request, HttpServletResponse response) {

        LoginAppUser loginAppUser = tokenService.getLoginAppUser(request);

        try {

            //防止重复
            AppSigninRecord appSigninRecord = new AppSigninRecord();
            appSigninRecord.setUserId(loginAppUser.getAppUser().getUserId());
            appSigninRecord.setSigninDate(DateUtils.dateTime());
            if (signinRecordService.getUpperAppSigninRecord(appSigninRecord.getUserId(), appSigninRecord.getSigninDate()) != null) {
                return AjaxResult.error("今天已签到过，请勿重复签到！");
            }

            //查询广告观看记录
            AppAdvertisementRecord appAdvertisementRecord = new AppAdvertisementRecord();
            appAdvertisementRecord.setUserId(loginAppUser.getAppUser().getUserId());
            appAdvertisementRecord.setAdvertisementType("3");
            appAdvertisementRecord.setState("3");
            appAdvertisementRecord.setCreateTime(DateUtils.getNowDate());
            if (appAdvertisementRecordService.getRecordNum(appAdvertisementRecord) > 0) {
                return AjaxResult.error("今天已签到过，请勿重复签到！");
            }

            //保存广告观看记录
            appAdvertisementRecord = new AppAdvertisementRecord();
            appAdvertisementRecord.setUserId(loginAppUser.getAppUser().getUserId());
            appAdvertisementRecord.setUserName(loginAppUser.getUsername());
            appAdvertisementRecord.setAdvertisementType("3");
            appAdvertisementRecord.setAdvertisementNum(IdUtils.getOrdercode(AppConstant.ORDERNUM_PREFIX_ADVERTISEMENT));
            appAdvertisementRecord.setState("1");
            appAdvertisementRecord.setCreateBy(loginAppUser.getUsername());
            appAdvertisementRecordService.insertAppAdvertisementRecord(appAdvertisementRecord);

            JSONObject result = new JSONObject();
            result.put("number", appAdvertisementRecord.getAdvertisementNum());
            result.put("source", "signIn");
            return AjaxResult.success("开始签到", result.toJSONString());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("签到失败！");
        }
    }

    /**
     * @throws
     * @title 用户签到
     * @description
     * @author admin
     * @updateTime 2021/3/4 9:12
     */
    @PreAuthorize("@ss.hasPermi('app:advertisement:signIn')")
    @ApiOperation(value = "用户签到（Android）")
    @RepeatSubmit
    @PostMapping("/signInAndroid")
    public AjaxResult signInAndroid(
            HttpServletRequest request, HttpServletResponse response) {
        LoginAppUser loginAppUser = tokenService.getLoginAppUser(request);
        String deviceID = request.getParameter("deviceID");
        try {
            //防止重复
            AppSigninRecord appSigninRecord = new AppSigninRecord();
            String userName = loginAppUser.getUsername();
            appSigninRecord.setUserId(loginAppUser.getAppUser().getUserId());
            appSigninRecord.setSigninDate(DateUtils.dateTime());
            if (ObjectUtils.isNotEmpty(deviceID)) {
                List<String> userNameList = userService.getDeviceIDNum(deviceID);
                if (ObjectUtils.isNotEmpty(userNameList) && userNameList.size() >= 2) {
                    if (!userNameList.contains(userName)) {
                        return AjaxResult.error("同一设备最多支持2个手机号登录");
                    }
                }
                SysUser sysUser = new SysUser();
                sysUser.setUserId(appSigninRecord.getUserId());
                sysUser.setDeviceID(deviceID);
                userService.updateDeviceID(sysUser);
            } else {
                return AjaxResult.error("请更新程序到最新版本");
            }
            AppSigninRecord check = signinRecordService.getUpperAppSigninRecord(appSigninRecord.getUserId(), appSigninRecord.getSigninDate());

            if (check != null) {
                Integer signinCount = check.getSigninCount() == null ? 0 : check.getSigninCount();
                if (signinCount >= maxCount) {
                    return AjaxResult.error("今天已签到过，请勿重复签到！");
                }
            }

            //查询广告观看记录
            AppAdvertisementRecord appAdvertisementRecord = new AppAdvertisementRecord();
            appAdvertisementRecord.setUserId(loginAppUser.getAppUser().getUserId());
            appAdvertisementRecord.setAdvertisementType("3");
            appAdvertisementRecord.setState("3");
            appAdvertisementRecord.setCreateTime(DateUtils.getNowDate());
            Integer num = appAdvertisementRecordService.getRecordNum(appAdvertisementRecord);
            if (num >= maxCount) {
                return AjaxResult.error("今天已签到过，请勿重复签到！");
            }
            //保存广告观看记录
            appAdvertisementRecord = insertAppAdvertisementRecord(loginAppUser);
            appAdvertisementRecordService.insertAppAdvertisementRecord(appAdvertisementRecord);
            return AjaxResult.success("开始签到", appAdvertisementRecord.getAdvertisementNum());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("签到失败！");
        }
    }

    private AppAdvertisementRecord insertAppAdvertisementRecord(LoginAppUser loginAppUser) {
        //保存广告观看记录
        AppAdvertisementRecord appAdvertisementRecord = new AppAdvertisementRecord();
        appAdvertisementRecord.setUserId(loginAppUser.getAppUser().getUserId());
        appAdvertisementRecord.setUserName(loginAppUser.getUsername());
        appAdvertisementRecord.setAdvertisementType("3");
        appAdvertisementRecord.setAdvertisementNum(IdUtils.getOrdercode(AppConstant.ORDERNUM_PREFIX_ADVERTISEMENT));
        appAdvertisementRecord.setState("1");
        appAdvertisementRecord.setCreateBy(loginAppUser.getUsername());
        appAdvertisementRecord.setCreateTime(DateUtils.getNowDate());
        return appAdvertisementRecord;
    }

    /**
     * @throws
     * @title 获取签到数据
     * @description
     * @author admin
     * @updateTime 2021/3/4 9:12
     */
    @PreAuthorize("@ss.hasPermi('app:advertisement:signIn')")
    @ApiOperation(value = "获取签到数据")
    @RepeatSubmit
    @PostMapping("/signInData")
    public AjaxResult signInData(
            HttpServletRequest request, HttpServletResponse response) {

        int days = 0;
        int isSignin = 0;//0未签到，1已签到，2签到中
        LoginAppUser loginAppUser = tokenService.getLoginAppUser(request);
        Long userId = loginAppUser.getAppUser().getUserId();
        AppSigninRecord appSigninRecord = signinRecordService.getUpperAppSigninRecord(userId, DateUtils.dateTime());
        Integer signinCount = 0;
        if (appSigninRecord != null) {
            days = appSigninRecord.getSigninContinuityDays();
            //本日签到次数
            signinCount = appSigninRecord.getSigninCount() == null ? 1 : appSigninRecord.getSigninCount();
            if (signinCount >= maxCount) {
                isSignin = 1;
            }
        } else {
            //查询昨天签到记录
            AppSigninRecord upperRecord = signinRecordService.getUpperAppSigninRecord(userId, DateUtils.dateCalculationDay(-1, "yyyyMMdd"));
            if (upperRecord != null) {
                days = upperRecord.getSigninContinuityDays();
            }
        }

        JSONObject object = new JSONObject();
        String money = configService.selectConfigByKey("app.signin.money");
        String money2 = configService.selectConfigByKey("app.signin.money2","0.03");
        String money3= configService.selectConfigByKey("app.signin.money3","0.01");
        String count2=configService.selectConfigByKey("app.signin.count2","100");
        String count3=configService.selectConfigByKey("app.signin.count3","200");
        SysUser sysUser = userService.selectUserById(userId);
        if (ObjectUtils.isNotEmpty(sysUser)) {
            Integer signCount = ObjectUtils.isNotEmpty(sysUser.getSignCount()) ? sysUser.getSignCount() : 0;
            if (signCount > Integer.parseInt(count2)) {
                money = money2;
            }
            if (signCount > Integer.parseInt(count3)) {
                money = money3;
            }
        }
        object.put("days", days);
        object.put("isSignin", isSignin);
        object.put("signinMoney", money);
        object.put("todayMoney", new BigDecimal(money).multiply(new BigDecimal(signinCount)));
        object.put("maxMoney", new BigDecimal(money).multiply(new BigDecimal(maxCount)));
        object.put("signinCount", signinCount);
        object.put("maxCount", maxCount);
        return AjaxResult.success(object);
    }

    /**
     * @throws
     * @title 广告回调（IOS）
     * @updateTime 2021/4/14 10:24
     */
    @GetMapping("/gatewayIOS")
    public String gatewayIOS(
            @RequestParam String appUserId,
            @RequestParam String rewardName,
            @RequestParam String extraInfo,
//            @RequestParam String sign,
            HttpServletRequest request, HttpServletResponse response
    ) {

        try {

            String sign = "test";
            if ((StringUtils.isBlank(appUserId)) || (StringUtils.isBlank(rewardName)) || (StringUtils.isBlank(extraInfo))) {
                logger.error("<advertisement.gatewayIOS>(appUserId={})(rewardName={})(extraInfo={})(sign={})参数错误", appUserId, rewardName, extraInfo, sign);
                return error();
            }
            logger.info("<advertisement.gatewayIOS>(appUserId={})(rewardName={})(extraInfo={})(sign={})", appUserId, rewardName, extraInfo, sign);
            extraInfo = URLDecoder.decode(extraInfo, "utf-8");
            JSONObject jsonObject = JSONObject.parseObject(extraInfo);
            if ("signIn".equals(jsonObject.getString("source"))) {
                AppAdvertisementRecord appAdvertisementRecord = appAdvertisementRecordService.selectAppAdvertisementRecordByNum(jsonObject.getString("number"));
                LoginAppUser loginAppUser = tokenService.getLoginAppUser(appAdvertisementRecord.getUserId());

                AppAdvertisementRecord appAdvertisementRecordQuery = new AppAdvertisementRecord();
                appAdvertisementRecordQuery.setUserId(loginAppUser.getAppUser().getUserId());
                appAdvertisementRecordQuery.setAdvertisementType("3");
                appAdvertisementRecordQuery.setState("3");
                appAdvertisementRecordQuery.setCreateTime(DateUtils.getNowDate());
                if (appAdvertisementRecordService.getRecordNum(appAdvertisementRecordQuery) == 0) {
                    loginAppUser = userService.appSignin(loginAppUser, appAdvertisementRecord);
                    tokenService.refreshToken(loginAppUser);
                    logger.info("用户<" + loginAppUser.getUsername() + ">签到成功");
                } else {
                    logger.info("用户<" + loginAppUser.getUsername() + ">已签到过，不再进行重复签到");
                }
            }

//            String appSecurityKey = configService.selectConfigByKey("app.advertisement.ios.appSecurityKey");
//            String signStr = Sha256Util.getSHA256(appSecurityKey + requestId);
//            if (!sign.equals(signStr)) {
//                logger.error("<advertisement.gatewayIOS>(userId={})(requestId={})(extra={})(sign={})验签失败", userId, requestId, extra, sign);
//                return error();
//            }
//            logger.info("<advertisement.gatewayIOS>(userId={})(requestId={})(extra={})(sign={})", userId, requestId, extra, sign);
//
//            //看完广告，业务处理
//            JSONObject jsonObject = JSONObject.parseObject(extra);
//            if ("signIn".equals(jsonObject.getString("source"))) {
//                //签到
//                AppAdvertisementRecord appAdvertisementRecord = appAdvertisementRecordService.selectAppAdvertisementRecordByNum(jsonObject.getString("number"));
//                LoginAppUser loginAppUser = tokenService.getLoginAppUser(appAdvertisementRecord.getUserId());
//                loginAppUser = userService.appSignin(loginAppUser, appAdvertisementRecord);
//                //刷新redis中用户信息
//                tokenService.refreshToken(loginAppUser);
//                logger.info("用户<" + loginAppUser.getUsername() + ">签到成功");
//            }
            return success();
        } catch (Exception e) {
            e.printStackTrace();
            return error();
        }
    }

    /**
     * @throws
     * @title 广告回调（Android）
     * @updateTime 2021/4/14 10:24
     */
    @GetMapping("/gatewayAndroid")
    public String gatewayAndroid(
            @RequestParam String userId,
            @RequestParam String requestId,
            @RequestParam String extra,
            @RequestParam String sign,
            HttpServletRequest request, HttpServletResponse response
    ) {

        try {

            if (StringUtils.isBlank(userId) || StringUtils.isBlank(requestId) || StringUtils.isBlank(sign)) {
                logger.error("<advertisement.gatewayAndroid>(userId={})(requestId={})(extra={})(sign={})参数错误", userId, requestId, extra, sign);
                return error();
            }
            String appSecurityKey = configService.selectConfigByKey("app.advertisement.anroid.appSecurityKey");
            String signStr = Sha256Util.getSHA256(appSecurityKey + requestId);
            if (!sign.equals(signStr)) {
                logger.error("<advertisement.gatewayAndroid>(userId={})(requestId={})(extra={})(sign={})验签失败", userId, requestId, extra, sign);
                return error();
            }

            logger.info("<advertisement.gatewayAndroid>(userId={})(requestId={})(extra={})(sign={})", userId, requestId, extra, sign);
            //看完广告，业务处理
            JSONObject jsonObject = JSONObject.parseObject(extra);
            if ("signIn".equals(jsonObject.getString("source"))) {
                //签到
                AppAdvertisementRecord appAdvertisementRecord = appAdvertisementRecordService.selectAppAdvertisementRecordByNum(jsonObject.getString("number"));
                LoginAppUser loginAppUser = tokenService.getLoginAppUser(appAdvertisementRecord.getUserId());
                loginAppUser = userService.appSignin(loginAppUser, appAdvertisementRecord);
                //刷新redis中用户信息
                tokenService.refreshToken(loginAppUser);
                logger.info("用户<" + loginAppUser.getUsername() + ">签到成功");
            }
            return success();
        } catch (Exception e) {
            e.printStackTrace();
            return error();
        }
    }

    @PreAuthorize("@ss.hasPermi('app:advertisement:signIn')")
    @ApiOperation(value = "用户签到回调")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderNum", value = "广告编号", required = true, dataType = "String", paramType = "query"),
    })
    @PostMapping("/signInGatewayAndroid")
    public AjaxResult signInGatewayAndroid(
            String orderNum,
            HttpServletRequest request, HttpServletResponse response) {

        try {

            if (StringUtils.isBlank(orderNum)) {
                return AjaxResult.error("编号不能为空");
            }
            AppAdvertisementRecord appAdvertisementRecord = appAdvertisementRecordService.selectAppAdvertisementRecordByNum(orderNum);
            if (appAdvertisementRecord == null) {
                return AjaxResult.error("编号错误");
            }
            if ("1".equals(appAdvertisementRecord.getState())) {
                LoginAppUser loginAppUser = tokenService.getLoginAppUser(request);
                loginAppUser = userService.appSignin(loginAppUser, appAdvertisementRecord);
                //刷新redis中用户信息
                tokenService.refreshToken(loginAppUser);
                logger.info("用户<" + loginAppUser.getUsername() + ">签到成功");
                return AjaxResult.success("签到成功");
            } else if ("2".equals(appAdvertisementRecord.getState())) {
                return AjaxResult.error("该广告已失效！");
            } else if ("3".equals(appAdvertisementRecord.getState())) {
                return AjaxResult.error("该广告已观看成功！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.error("签到失败！");
    }

    /**
     * @throws
     * @title 福利社福豆兑换回调
     * @updateTime 2021/4/14 10:24
     */
    @PostMapping(value = "/fulishe/gateway", produces = "application/json;charset=UTF-8")
    public JSONObject fulisheGateway(
            @RequestBody JSONObject object,
            HttpServletRequest request, HttpServletResponse response
    ) {

        JSONObject jsonObject = new JSONObject();
        try {
            logger.info("<advertisement.fulishe.gateway><object：{}>", object.toJSONString());

            String channelId = object.getString("channel_id");
            String userId = object.getString("user_id");
            String orderNo = object.getString("order_no");
            String sign = object.getString("sign");
            String useCoinNumStr = object.getString("use_coin_num");//用户使用平台积分数量
            String appSecurityKey = configService.selectConfigByKey("app.advertisement.fulishe.appSecurityKey");
            String signStr = Md5Utils.hash(channelId + userId + orderNo + appSecurityKey);
            if (!sign.equals(signStr)) {
                return FAIL();
            }
            int useCoinNum = (int) Double.parseDouble(useCoinNumStr);
            //TODO 福豆兑换规则：最少兑换2000，必须是200的倍数
//            if (useCoinNum % 200 > 0 || useCoinNum < 2000) {
//                return fail();
//            }
            LoginAppUser loginAppUser = tokenService.getLoginAppUser(Long.valueOf(userId));
            BigDecimal money = new BigDecimal(object.getString("exchange_num"));
            //只留2位小数
            money = money.setScale(2, BigDecimal.ROUND_DOWN);
            loginAppUser = userService.withdrawalFulishe(loginAppUser, money);
            //刷新redis中用户信息
            tokenService.refreshToken(loginAppUser);
            logger.info("<advertisement.fulishe.gateway>用户{}}福豆提现成功，共提现{}个福豆，提现金额为{}", loginAppUser.getUsername(), useCoinNum, money);
            return OK();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("<advertisement.fulishe.gateway>兑换福豆失败，{}", e.getMessage());
            return FAIL();
        }
    }

    private final static JSONObject OK() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 200);
        jsonObject.put("msg", "成功");
        return jsonObject;
    }

    private final static JSONObject FAIL() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 500);
        jsonObject.put("msg", "失败");
        return jsonObject;
    }

    private final static String success() {
        JSONObject object = new JSONObject();
        object.put("isValid", true);
        return object.toJSONString();
    }

    private final static String error() {
        JSONObject object = new JSONObject();
        object.put("isValid", false);
        return object.toJSONString();
    }

}
